home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / IEditor / locale.c < prev    next >
C/C++ Source or Header  |  1997-06-17  |  40KB  |  1,883 lines

  1. /// Include
  2. #define INTUI_V36_NAMES_ONLY
  3. #define ASL_V38_NAMES_ONLY
  4. #define CATCOMP_NUMBERS
  5.  
  6. #include <exec/types.h>                 // exec
  7. #include <exec/memory.h>
  8. #include <dos/dos.h>                    // dos
  9. #include <intuition/intuition.h>        // intuition
  10. #include <libraries/gadtools.h>         // libraries
  11. #include <libraries/iffparse.h>
  12. #include <clib/exec_protos.h>           // protos
  13. #include <clib/dos_protos.h>
  14. #include <clib/intuition_protos.h>
  15. #include <clib/gadtools_protos.h>
  16. #include <clib/reqtools_protos.h>
  17. #include <clib/iffparse_protos.h>
  18. #include <pragmas/exec_pragmas.h>       // pragmas
  19. #include <pragmas/dos_pragmas.h>
  20. #include <pragmas/intuition_pragmas.h>
  21. #include <pragmas/dos_pragmas.h>
  22. #include <pragmas/gadtools_pragmas.h>
  23. #include <pragmas/reqtools_pragmas.h>
  24. #include <pragmas/iffparse_pragmas.h>
  25.  
  26. #include <string.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29.  
  30. #include "DEV_IE:defs.h"
  31. #include "DEV_IE:GUI.h"
  32. #include "DEV_IE:GUI_locale.h"
  33. ///
  34. /// Prototypes
  35. static void     HandleLocale( void );
  36. static void     DetacheLangList( void );
  37. static void     AttachLangList( void );
  38. static void     DetacheStrList( void );
  39. static void     AttachStrList( void );
  40. static void     DetacheNSList( void );
  41. static void     AttachNSList( void );
  42. static BOOL     GetLine( STRPTR, UBYTE **, UBYTE * );
  43. static BOOL     EditLang( struct LocaleLanguage * );
  44. static BOOL     EditString( struct LocaleStr * );
  45. static BOOL     EditTranslation( struct LocaleTranslation * );
  46. static BOOL     AddString( UBYTE * );
  47. static UWORD    CountArray( UBYTE ** );
  48. static BOOL     CmpArrays( UBYTE **, struct MinList * );
  49. static BOOL     ProcessGadgets( struct MinList * );
  50. static void     FreeLangStr( UBYTE );
  51. static struct LocaleTranslation *GetTranslation( STRPTR );
  52. static void     FreeUnusedTranslations( void );
  53. static void     ImportStrings( STRPTR, BOOL );
  54. static BOOL     WriteCD( STRPTR );
  55. static void     WriteCT( STRPTR, UBYTE );
  56. static void     Import( STRPTR, struct MinList * );
  57. static void     DetacheImpLists( void );
  58. static void     AttachImpLists( void );
  59. ///
  60. /// Data
  61. static TEXT CatName[60];
  62. static TEXT LocJoin[256];
  63. static TEXT LocBuiltIn[30];
  64.  
  65. struct LocaleData LocInfo = {
  66.     CatName,
  67.     LocJoin,
  68.     LocBuiltIn,
  69.     0,
  70.     { &LocInfo.ExtraStrings.mlh_Tail, 0, &LocInfo.ExtraStrings.mlh_Head },
  71.     { &LocInfo.Languages.mlh_Tail,    0, &LocInfo.Languages.mlh_Head    },
  72.     { &LocInfo.Translations.mlh_Tail, 0, &LocInfo.Translations.mlh_Head },
  73.     { &LocInfo.Arrays.mlh_Tail,       0, &LocInfo.Arrays.mlh_Head },
  74. };
  75.  
  76. static UBYTE                     SelectedLang, T_Language;
  77. static struct LocaleStr         *SelectedString, *EditingStr, *StrInsert;
  78. static struct LocaleTranslation *SelectedTran;
  79.  
  80. static UBYTE                    ScrFlagsBack;
  81. static BOOL                     EL_RetCode, ET_RetCode, StrList = FALSE;
  82.  
  83. static struct MinList           *ImportList;
  84. ///
  85.  
  86.  
  87. /// LocaleMenued
  88. BOOL LocaleMenued( void )
  89. {
  90.     int     ret;
  91.  
  92.     if( LocaleWnd ) {
  93.     ActivateWindow( LocaleWnd );
  94.     WindowToFront( LocaleWnd );
  95.     return( TRUE );
  96.     }
  97.  
  98.     LayoutWindow( LocaleWTags );
  99.     ret = OpenLocaleWindow();
  100.     PostOpenWindow( LocaleWTags );
  101.  
  102.     if( ret ) {
  103.     DisplayBeep( Scr );
  104.     CloseLocaleWindow();
  105.     } else {
  106.     APTR    lock;
  107.  
  108.     lock = rtLockWindow( LocaleWnd );
  109.  
  110.     StringTag[1] = IE.Locale->Catalog;
  111.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_CatName ], LocaleWnd,
  112.                 NULL, (struct TagItem *)StringTag );
  113.  
  114.     StringTag[1] = IE.Locale->JoinFile;
  115.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Join ], LocaleWnd,
  116.                 NULL, (struct TagItem *)StringTag );
  117.  
  118.     StringTag[1] = IE.Locale->BuiltIn;
  119.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_BuiltIn ], LocaleWnd,
  120.                 NULL, (struct TagItem *)StringTag );
  121.  
  122.     IntegerTag[1] = IE.Locale->Version;
  123.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Vers ], LocaleWnd,
  124.                 NULL, (struct TagItem *)IntegerTag );
  125.  
  126.     CheckedTag[1] = ( IE.SrcFlags & LOCALIZE ) ? TRUE : FALSE;
  127.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_On ], LocaleWnd,
  128.                 NULL, (struct TagItem *)CheckedTag );
  129.  
  130.     AttachLangList();
  131.  
  132.     if(!( GetStrings() ))
  133.         Stat( CatCompArray[ ERR_NOMEMORY ].cca_Str, TRUE, 0 );
  134.  
  135.     for( StrInsert = IE.Locale->ExtraStrings.mlh_Head; StrInsert->Node.ln_Succ; StrInsert = StrInsert->Node.ln_Succ )
  136.         if( StrInsert->Node.ln_Pri & LOC_GUI ) {
  137.         StrInsert = StrInsert->Node.ln_Pred;
  138.         break;
  139.         }
  140.  
  141.     AttachStrList();
  142.  
  143.     ScrFlagsBack = IE.SrcFlags;
  144.  
  145.     LocaleWnd->ExtData = HandleLocale;
  146.  
  147.     rtUnlockWindow( LocaleWnd, lock );
  148.     }
  149.  
  150.     return( TRUE );
  151. }
  152.  
  153. void HandleLocale( void )
  154. {
  155.     if(!( HandleLocaleIDCMP() )) {
  156.        CloseLocaleWindow();
  157.  
  158.        PutStrings();
  159.     }
  160. }
  161.  
  162. BOOL LOC_OnKeyPressed( void )
  163. {
  164.     CheckedTag[1] = ( IE.SrcFlags & LOCALIZE ) ? FALSE : TRUE;
  165.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_On ], LocaleWnd,
  166.             NULL, (struct TagItem *)CheckedTag );
  167.  
  168.     return( LOC_OnClicked() );
  169. }
  170.  
  171. BOOL LOC_OnClicked( void )
  172. {
  173.     IE.SrcFlags ^= LOCALIZE;
  174.     return( TRUE );
  175. }
  176.  
  177. BOOL LOC_OkKeyPressed( void )
  178. {
  179.     return( LOC_OkClicked() );
  180. }
  181.  
  182. BOOL LOC_OkClicked( void )
  183. {
  184.     strcpy( IE.Locale->Catalog, GetString( LocaleGadgets[ GD_LOC_CatName ]) );
  185.     strcpy( IE.Locale->JoinFile, GetString( LocaleGadgets[ GD_LOC_Join ]) );
  186.     strcpy( IE.Locale->BuiltIn, GetString( LocaleGadgets[ GD_LOC_BuiltIn ]) );
  187.  
  188.     IE.Locale->Version = GetNumber( LocaleGadgets[ GD_LOC_Vers ]);
  189.  
  190.     return( FALSE );
  191. }
  192.  
  193. BOOL LOC_AnnullaKeyPressed( void )
  194. {
  195.     return( LOC_AnnullaClicked() );
  196. }
  197.  
  198. BOOL LOC_AnnullaClicked( void )
  199. {
  200.     IE.SrcFlags = ScrFlagsBack;
  201.  
  202.     return( FALSE );
  203. }
  204.  
  205. BOOL LOC_CatNameClicked( void )
  206. {
  207.     ActivateGadget( LocaleGadgets[ GD_LOC_Join ], LocaleWnd, NULL );
  208.     return( TRUE );
  209. }
  210.  
  211. BOOL LOC_JoinClicked( void )
  212. {
  213.     ActivateGadget( LocaleGadgets[ GD_LOC_BuiltIn ], LocaleWnd, NULL );
  214.     return( TRUE );
  215. }
  216.  
  217. BOOL LOC_BuiltInClicked( void )
  218. {
  219.     ActivateGadget( LocaleGadgets[ GD_LOC_Vers ], LocaleWnd, NULL );
  220.     return( TRUE );
  221. }
  222.  
  223. BOOL LOC_VersClicked( void )
  224. {
  225.     return( TRUE );
  226. }
  227.  
  228. BOOL LocaleVanillaKey( void )
  229. {
  230.     switch( IDCMPMsg.Code ) {
  231.     case 13:
  232.         return( LOC_OkClicked() );
  233.  
  234.     case 27:
  235.         return( LOC_AnnullaClicked() );
  236.     }
  237.  
  238.     return( TRUE );
  239. }
  240.  
  241. BOOL LOC_GetJoinClicked( void )
  242. {
  243.     if( GetFile2( FALSE, CatCompArray[ ASL_GET_CATALOG ].cca_Str, "#?.cd",
  244.           ASL_GET_CATALOG, "cd" )) {
  245.  
  246.     StringTag[1] = allpath2;
  247.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Join ], LocaleWnd,
  248.                 NULL, (struct TagItem *)StringTag );
  249.     }
  250.  
  251.     return( TRUE );
  252. }
  253.  
  254. BOOL LOC_NewLangKeyPressed( void )
  255. {
  256.     return( LOC_NewLangClicked() );
  257. }
  258.  
  259. BOOL LOC_DelLangKeyPressed( void )
  260. {
  261.     return( LOC_DelLangClicked() );
  262. }
  263.  
  264. BOOL LOC_LangClicked( void )
  265. {
  266.     static ULONG  Secs = 0, Micros = 0;
  267.  
  268.     if( DoubleClick( Secs, Micros, IDCMPMsg.Seconds, IDCMPMsg.Micros )) {
  269.     if( SelectedLang == IDCMPMsg.Code ) {
  270.         ULONG                   cnt;
  271.         struct LocaleLanguage  *lang;
  272.  
  273.         lang = IE.Locale->Languages.mlh_Head;
  274.  
  275.         for( cnt = 0; cnt < IDCMPMsg.Code; cnt++ )
  276.         lang = lang->Node.ln_Succ;
  277.  
  278.         EditLang( lang );
  279.     }
  280.     }
  281.  
  282.     SelectedLang = IDCMPMsg.Code;
  283.     Secs         = IDCMPMsg.Seconds;
  284.     Micros       = IDCMPMsg.Micros;
  285.  
  286.     List2Tag[1] = List2Tag[3] = (ULONG)IDCMPMsg.Code;
  287.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Lang ], LocaleWnd,
  288.             NULL, (struct TagItem *)List2Tag );
  289.  
  290.     return( TRUE );
  291. }
  292.  
  293. BOOL LOC_NewLangClicked( void )
  294. {
  295.     struct LocaleLanguage  *lang;
  296.  
  297.     if( lang = AllocObject( IE_LOCALE_LANGUAGE )) {
  298.  
  299.     if( EditLang( lang )) {
  300.  
  301.         DetacheLangList();
  302.         AddTail(( struct List * )&IE.Locale->Languages, ( struct Node * )lang );
  303.         AttachLangList();
  304.  
  305.     } else
  306.         FreeObject( lang, IE_LOCALE_LANGUAGE );
  307.  
  308.     } else
  309.     Stat( CatCompArray[ ERR_NOMEMORY ].cca_Str, TRUE, 0 );
  310.  
  311.     return( TRUE );
  312. }
  313.  
  314. BOOL LOC_DelLangClicked( void )
  315. {
  316.     if( SelectedLang != (UBYTE)-1 ) {
  317.     struct LocaleLanguage  *lang;
  318.     ULONG                   cnt;
  319.  
  320.     lang = IE.Locale->Languages.mlh_Head;
  321.  
  322.     for( cnt = 0; cnt < SelectedLang; cnt++ )
  323.         lang = lang->Node.ln_Succ;
  324.  
  325.     FreeLangStr( SelectedLang );
  326.  
  327.     DetacheLangList();
  328.     Remove(( struct Node * )lang );
  329.     FreeObject( lang, IE_LOCALE_LANGUAGE );
  330.     AttachLangList();
  331.     }
  332.  
  333.     return( TRUE );
  334. }
  335.  
  336. BOOL LOC_DelStrClicked( void )
  337. {
  338.     if( SelectedString ) {
  339.  
  340.     if( StrInsert == SelectedString )
  341.         StrInsert = SelectedString->Node.ln_Pred;
  342.  
  343.     DetacheStrList();
  344.     Remove(( struct Node * )SelectedString );
  345.     FreeObject( SelectedString, IE_LOCALE_STRING );
  346.     AttachStrList();
  347.     }
  348.  
  349.     return( TRUE );
  350. }
  351.  
  352. BOOL LOC_StringsClicked( void )
  353. {
  354.     static ULONG        Secs = 0, Micros = 0;
  355.     ULONG               cnt;
  356.     struct LocaleStr   *str;
  357.  
  358.     str = IE.Locale->ExtraStrings.mlh_Head;
  359.  
  360.     for( cnt = 0; cnt < IDCMPMsg.Code; cnt++ )
  361.     str = str->Node.ln_Succ;
  362.  
  363.     if( DoubleClick( Secs, Micros, IDCMPMsg.Seconds, IDCMPMsg.Micros )) {
  364.     if( SelectedString == str )
  365.         EditString( SelectedString );
  366.     }
  367.  
  368.     SelectedString = str;
  369.     Secs           = IDCMPMsg.Seconds;
  370.     Micros         = IDCMPMsg.Micros;
  371.  
  372.     DisableTag[1] = ( str->Node.ln_Pri & LOC_GUI ) ? TRUE : FALSE;
  373.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_DelStr ], LocaleWnd,
  374.             NULL, ( struct TagItem * )DisableTag );
  375.  
  376.     return( TRUE );
  377. }
  378.  
  379. BOOL LOC_NewStrClicked( void )
  380. {
  381.     struct LocaleStr   *string;
  382.  
  383.     if( string = AllocObject( IE_LOCALE_STRING )) {
  384.  
  385.     if( EditString( string )) {
  386.  
  387.         DetacheStrList();
  388.         Insert(( struct List * )&IE.Locale->ExtraStrings, ( struct Node * )string, ( struct Node * )StrInsert );
  389.         StrInsert = string;
  390.         AttachStrList();
  391.  
  392.     } else
  393.         FreeObject( string, IE_LOCALE_STRING );
  394.  
  395.     } else
  396.     Stat( CatCompArray[ ERR_NOMEMORY ].cca_Str, TRUE, 0 );
  397.  
  398.     return( TRUE );
  399. }
  400. ///
  401. /// List handling
  402. void DetacheLangList( void )
  403. {
  404.     ListTag[1] = (ULONG)~0;
  405.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Lang ], LocaleWnd,
  406.             NULL, (struct TagItem *)ListTag );
  407. }
  408.  
  409. void AttachLangList( void )
  410. {
  411.     ListTag[1] = (ULONG)&IE.Locale->Languages;
  412.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Lang ], LocaleWnd,
  413.             NULL, (struct TagItem *)ListTag );
  414.  
  415.     List2Tag[3] = (ULONG)~0;
  416.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Lang ], LocaleWnd,
  417.             NULL, (struct TagItem *)&List2Tag[2] );
  418.  
  419.     SelectedLang = (UBYTE)-1;
  420. }
  421.  
  422. void DetacheStrList( void )
  423. {
  424.     ListTag[1] = (ULONG)~0;
  425.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Strings ], LocaleWnd,
  426.             NULL, (struct TagItem *)ListTag );
  427. }
  428.  
  429. void AttachStrList( void )
  430. {
  431.     ListTag[1] = (ULONG)&IE.Locale->ExtraStrings;
  432.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Strings ], LocaleWnd,
  433.             NULL, (struct TagItem *)ListTag );
  434.  
  435.     List2Tag[3] = (ULONG)~0;
  436.     GT_SetGadgetAttrsA( LocaleGadgets[ GD_LOC_Strings ], LocaleWnd,
  437.             NULL, (struct TagItem *)&List2Tag[2] );
  438.  
  439.     SelectedString = NULL;
  440. }
  441. ///
  442.  
  443. /// EditLang
  444. BOOL EditLang( struct LocaleLanguage *Lang )
  445. {
  446.     APTR    lock;
  447.     BOOL    ret = FALSE, w;
  448.  
  449.     LockAllWindows();
  450.     lock = rtLockWindow( LocaleWnd );
  451.  
  452.     DetacheLangList();
  453.  
  454.     LayoutWindow( LanguageWTags );
  455.     w = OpenLanguageWindow();
  456.     PostOpenWindow( LanguageWTags );
  457.  
  458.     if( w )
  459.     DisplayBeep( Scr );
  460.     else {
  461.  
  462.     StringTag[1] = (ULONG)Lang->Language;
  463.     GT_SetGadgetAttrsA( LanguageGadgets[ GD_LANG_Lang ], LanguageWnd,
  464.                 NULL, ( struct TagItem * )StringTag );
  465.  
  466.     StringTag[1] = (ULONG)Lang->File;
  467.     GT_SetGadgetAttrsA( LanguageGadgets[ GD_LANG_File ], LanguageWnd,
  468.                 NULL, ( struct TagItem * )StringTag );
  469.  
  470.     do {
  471.         WaitPort( LanguageWnd->UserPort );
  472.     } while( HandleLanguageIDCMP() );
  473.  
  474.     if( EL_RetCode ) {
  475.         strcpy( Lang->Language, GetString( LanguageGadgets[ GD_LANG_Lang ] ));
  476.         strcpy( Lang->File, GetString( LanguageGadgets[ GD_LANG_File ] ));
  477.  
  478.         ret = TRUE;
  479.     }
  480.     }
  481.  
  482.     CloseLanguageWindow();
  483.  
  484.     AttachLangList();
  485.  
  486.     rtUnlockWindow( LocaleWnd, lock );
  487.     UnlockAllWindows();
  488.  
  489.     return( ret );
  490. }
  491.  
  492. BOOL LanguageVanillaKey( void )
  493. {
  494.     switch( LanguageMsg.Code ) {
  495.     case 13:
  496.         return( LANG_OkClicked() );
  497.  
  498.     case 27:
  499.         return( LANG_CancelClicked() );
  500.     }
  501.  
  502.     return( TRUE );
  503. }
  504.  
  505. BOOL LANG_OkKeyPressed( void )
  506. {
  507.     return( LANG_OkClicked() );
  508. }
  509.  
  510. BOOL LANG_CancelKeyPressed( void )
  511. {
  512.     return( LANG_CancelClicked() );
  513. }
  514.  
  515. BOOL LANG_OkClicked( void )
  516. {
  517.     EL_RetCode = TRUE;
  518.  
  519.     IE.flags &= ~SALVATO;
  520.  
  521.     return( FALSE );
  522. }
  523.  
  524. BOOL LANG_CancelClicked( void )
  525. {
  526.     EL_RetCode = FALSE;
  527.  
  528.     return( FALSE );
  529. }
  530.  
  531. BOOL LANG_LangClicked( void )
  532. {
  533.     return( TRUE );
  534. }
  535.  
  536. BOOL LANG_FileClicked( void )
  537. {
  538.     return( TRUE );
  539. }
  540.  
  541. BOOL LANG_GetFileClicked( void )
  542. {
  543.     if( GetFile2( FALSE, CatCompArray[ ASL_SELECT_CT ].cca_Str, NULL,
  544.           ASL_SELECT_CT, NULL )) {
  545.  
  546.     StringTag[1] = allpath2;
  547.     GT_SetGadgetAttrsA( LanguageGadgets[ GD_LANG_File ], LanguageWnd,
  548.                 NULL, (struct TagItem *)StringTag );
  549.     }
  550.  
  551.     return( TRUE );
  552. }
  553. ///
  554. /// EditString
  555. BOOL EditString( struct LocaleStr *String )
  556. {
  557.     APTR    lock;
  558.     BOOL    ret = FALSE, w;
  559.  
  560.     LockAllWindows();
  561.     lock = rtLockWindow( LocaleWnd );
  562.  
  563.     DetacheStrList();
  564.  
  565.     LayoutWindow( NewStrWTags );
  566.     w = OpenNewStrWindow();
  567.     PostOpenWindow( NewStrWTags );
  568.  
  569.     if( w )
  570.     DisplayBeep( Scr );
  571.     else {
  572.  
  573.     EditingStr = String;
  574.  
  575.     StringTag[1] = String->Node.ln_Name;
  576.     GT_SetGadgetAttrsA( NewStrGadgets[ GD_NS_Str ], NewStrWnd,
  577.                 NULL, ( struct TagItem * )StringTag );
  578.  
  579.     if( String->Node.ln_Pri & LOC_GUI ) {
  580.  
  581.         DisableTag[1] = TRUE;
  582.         GT_SetGadgetAttrsA( NewStrGadgets[ GD_NS_ID ], NewStrWnd,
  583.                 NULL, ( struct TagItem * )DisableTag );
  584.  
  585.     } else {
  586.  
  587.         StringTag[1] = String->ID;
  588.         GT_SetGadgetAttrsA( NewStrGadgets[ GD_NS_ID ], NewStrWnd,
  589.                 NULL, ( struct TagItem * )StringTag );
  590.     }
  591.  
  592.     AttachNSList();
  593.  
  594.     ActivateGadget( NewStrGadgets[ GD_NS_Str ], NewStrWnd, NULL );
  595.  
  596.     do {
  597.         WaitPort( NewStrWnd->UserPort );
  598.     } while( HandleNewStrIDCMP() );
  599.  
  600.     if( EL_RetCode ) {
  601.  
  602.         ret = TRUE;
  603.  
  604.         if(!( String->Node.ln_Pri & LOC_GUI ))
  605.         strcpy( String->String, GetString( NewStrGadgets[ GD_NS_Str ] ));
  606.  
  607.         strcpy( String->ID, GetString( NewStrGadgets[ GD_NS_ID ] ));
  608.     }
  609.     }
  610.  
  611.     AttachStrList();
  612.  
  613.     CloseNewStrWindow();
  614.  
  615.     rtUnlockWindow( LocaleWnd, lock );
  616.     UnlockAllWindows();
  617.  
  618.     return( ret );
  619. }
  620.  
  621. void DetacheNSList( void )
  622. {
  623.     ListTag[1] = (ULONG)~0;
  624.     GT_SetGadgetAttrsA( NewStrGadgets[ GD_NS_Tran ], NewStrWnd,
  625.             NULL, (struct TagItem *)ListTag );
  626. }
  627.  
  628. void AttachNSList( void )
  629. {
  630.     ListTag[1] = (ULONG)&EditingStr->Translations;
  631.     GT_SetGadgetAttrsA( NewStrGadgets[ GD_NS_Tran ], NewStrWnd,
  632.             NULL, (struct TagItem *)ListTag );
  633.  
  634.     List2Tag[3] = (ULONG)~0;
  635.     GT_SetGadgetAttrsA( NewStrGadgets[ GD_NS_Tran ], NewStrWnd,
  636.             NULL, (struct TagItem *)&List2Tag[2] );
  637.  
  638.     SelectedTran = NULL;
  639. }
  640.  
  641. BOOL NewStrVanillaKey( void )
  642. {
  643.  
  644.     switch( NewStrMsg.Code ) {
  645.     case 13:
  646.         return( NS_OkClicked() );
  647.  
  648.     case 27:
  649.         return( NS_CancelClicked() );
  650.     }
  651.  
  652.     return( TRUE );
  653. }
  654.  
  655. BOOL NS_OkKeyPressed( void )
  656. {
  657.     return( NS_OkClicked() );
  658. }
  659.  
  660. BOOL NS_CancelKeyPressed( void )
  661. {
  662.     return( NS_CancelClicked() );
  663. }
  664.  
  665. BOOL NS_NewKeyPressed( void )
  666. {
  667.     return( NS_NewClicked() );
  668. }
  669.  
  670. BOOL NS_DelKeyPressed( void )
  671. {
  672.     return( NS_DelClicked() );
  673. }
  674.  
  675. BOOL NS_StrClicked( void )
  676. {
  677.     return( TRUE );
  678. }
  679.  
  680. BOOL NS_IDClicked( void )
  681. {
  682.     return( TRUE );
  683. }
  684.  
  685. BOOL NS_OkClicked( void )
  686. {
  687.     EL_RetCode = TRUE;
  688.  
  689.     IE.flags &= ~SALVATO;
  690.  
  691.     return( FALSE );
  692. }
  693.  
  694. BOOL NS_CancelClicked( void )
  695. {
  696.     EL_RetCode = FALSE;
  697.  
  698.     return( FALSE );
  699. }
  700.  
  701. BOOL NS_NewClicked( void )
  702. {
  703.     struct LocaleTranslation   *tran;
  704.  
  705.     if( tran = AllocObject( IE_LOCALE_TRANSLATION )) {
  706.  
  707.     if( EditTranslation( tran )) {
  708.  
  709.         DetacheNSList();
  710.         AddTail(( struct List * )&EditingStr->Translations, ( struct Node * )tran );
  711.         AttachNSList();
  712.  
  713.     } else
  714.         FreeObject( tran, IE_LOCALE_TRANSLATION );
  715.  
  716.     } else
  717.     Stat( CatCompArray[ ERR_NOMEMORY ].cca_Str, TRUE, 0 );
  718.  
  719.     return( TRUE );
  720. }
  721.  
  722. BOOL NS_DelClicked( void )
  723. {
  724.     if( SelectedTran ) {
  725.  
  726.     DetacheNSList();
  727.     Remove(( struct Node * )SelectedTran );
  728.     FreeObject( SelectedTran, IE_LOCALE_TRANSLATION );
  729.     AttachNSList();
  730.     }
  731.  
  732.     return( TRUE );
  733. }
  734.  
  735. BOOL NS_TranClicked( void )
  736. {
  737.     static ULONG                Secs = 0, Micros = 0;
  738.     ULONG                       cnt;
  739.     struct LocaleTranslation   *tran;
  740.  
  741.     tran = EditingStr->Translations.mlh_Head;
  742.  
  743.     for( cnt = 0; cnt < NewStrMsg.Code; cnt++ )
  744.     tran = tran->Node.ln_Succ;
  745.  
  746.     if( DoubleClick( Secs, Micros, NewStrMsg.Seconds, NewStrMsg.Micros )) {
  747.     if( SelectedTran == tran ) {
  748.         DetacheNSList();
  749.         EditTranslation( SelectedTran );
  750.         AttachNSList();
  751.     }
  752.     }
  753.  
  754.     SelectedTran = tran;
  755.     Secs         = NewStrMsg.Seconds;
  756.     Micros       = NewStrMsg.Micros;
  757.  
  758.     List2Tag[1] = List2Tag[3] = (ULONG)NewStrMsg.Code;
  759.     GT_SetGadgetAttrsA( NewStrGadgets[ GD_NS_Tran ], NewStrWnd,
  760.             NULL, (struct TagItem *)List2Tag );
  761.  
  762.     return( TRUE );
  763. }
  764. ///
  765. /// EditTranslation
  766. BOOL EditTranslation( struct LocaleTranslation *tran )
  767. {
  768.     APTR    lock;
  769.     BOOL    ret = FALSE, w;
  770.  
  771.     lock = rtLockWindow( NewStrWnd );
  772.  
  773.     LayoutWindow( TranslationWTags );
  774.     w = OpenTranslationWindow();
  775.     PostOpenWindow( TranslationWTags );
  776.  
  777.     if( w )
  778.     DisplayBeep( Scr );
  779.     else {
  780.  
  781.     if( tran->String ) {
  782.         StringTag[1] = (ULONG)tran->String;
  783.         GT_SetGadgetAttrsA( TranslationGadgets[ GD_T_Str ], TranslationWnd,
  784.                 NULL, ( struct TagItem * )StringTag );
  785.     }
  786.  
  787.     ListTag[1] = (ULONG)&IE.Locale->Languages;
  788.     GT_SetGadgetAttrsA( TranslationGadgets[ GD_T_Lang ], TranslationWnd,
  789.                 NULL, ( struct TagItem * )ListTag );
  790.  
  791.     List2Tag[1] = List2Tag[3] = tran->Node.ln_Type;
  792.     GT_SetGadgetAttrsA( TranslationGadgets[ GD_T_Lang ], TranslationWnd,
  793.                 NULL, ( struct TagItem * )List2Tag );
  794.  
  795.     ActivateGadget( TranslationGadgets[ GD_T_Str ], TranslationWnd, NULL );
  796.  
  797.     T_Language = tran->Node.ln_Type;
  798.  
  799.     do {
  800.         WaitPort( TranslationWnd->UserPort );
  801.     } while( HandleTranslationIDCMP() );
  802.  
  803.     if( ET_RetCode ) {
  804.         STRPTR  str;
  805.  
  806.         ret = TRUE;
  807.  
  808.         FreeVec( tran->String );
  809.  
  810.         str = GetString( TranslationGadgets[ GD_T_Str ]);
  811.  
  812.         if( tran->String = AllocVec( strlen( str ) + 1, MEMF_ANY ))
  813.         strcpy( tran->String, str );
  814.         else
  815.         DisplayBeep( Scr );
  816.  
  817.         tran->Node.ln_Name = tran->String;
  818.         tran->Node.ln_Type = T_Language;
  819.     }
  820.     }
  821.  
  822.     CloseTranslationWindow();
  823.  
  824.     rtUnlockWindow( NewStrWnd, lock );
  825.  
  826.     return( ret );
  827. }
  828.  
  829. BOOL TranslationVanillaKey( void )
  830. {
  831.     switch( TranslationMsg.Code ) {
  832.     case 13:
  833.         return( T_OkClicked() );
  834.  
  835.     case 27:
  836.         return( T_CancelClicked() );
  837.     }
  838.  
  839.     return( TRUE );
  840. }
  841.  
  842. BOOL T_OkKeyPressed( void )
  843. {
  844.     return( T_OkClicked() );
  845. }
  846.  
  847. BOOL T_CancelKeyPressed( void )
  848. {
  849.     return( T_CancelClicked() );
  850. }
  851.  
  852. BOOL T_StrClicked( void )
  853. {
  854.     return( TRUE );
  855. }
  856.  
  857. BOOL T_OkClicked( void )
  858. {
  859.     ET_RetCode = TRUE;
  860.  
  861.     IE.flags &= ~SALVATO;
  862.  
  863.     return( FALSE );
  864. }
  865.  
  866. BOOL T_CancelClicked( void )
  867. {
  868.     ET_RetCode = FALSE;
  869.  
  870.     return( FALSE );
  871. }
  872.  
  873. BOOL T_LangClicked( void )
  874. {
  875.     T_Language = TranslationMsg.Code;
  876.  
  877.     return( TRUE );
  878. }
  879. ///
  880.  
  881. /// ImpStrClicked
  882. BOOL LOC_ImpStrClicked( void )
  883. {
  884.     APTR    lock;
  885.  
  886.     LockAllWindows();
  887.     lock = rtLockWindow( LocaleWnd );
  888.  
  889.     DetacheStrList();
  890.  
  891.     if( GetFile2( FALSE, CatCompArray[ ASL_IMPORT_STRINGS ].cca_Str, "#?.cd",
  892.           ASL_IMPORT_STRINGS, "cd" )) {
  893.  
  894.     ImportStrings( allpath2, FALSE );
  895.     }
  896.  
  897.     AttachStrList();
  898.  
  899.     rtUnlockWindow( LocaleWnd, lock );
  900.     UnlockAllWindows();
  901.  
  902.     return( TRUE );
  903. }
  904. ///
  905. /// ImportStrings
  906. void ImportStrings( STRPTR FileName, BOOL Free )
  907. {
  908.     BPTR    file;
  909.  
  910.     if( file = Open( FileName, MODE_OLDFILE )) {
  911.     LONG    size;
  912.     UBYTE  *buffer;
  913.  
  914.     Seek( file, 0, OFFSET_END );
  915.     size = Seek( file, 0, OFFSET_BEGINNING );
  916.  
  917.     if( buffer = AllocMem( size, MEMF_CLEAR )) {
  918.         TEXT    str[512];
  919.         UBYTE  *strings, *end;
  920.  
  921.         Read( file, buffer, size );
  922.  
  923.         strings  = buffer;
  924.         end      = buffer + size;
  925.  
  926.         while( GetLine( str, &strings, end )) {
  927.         TEXT    str2[512];
  928.         STRPTR  par;
  929.  
  930.         if( par = strchr( str, '(' ))
  931.             *par = '\0';
  932.  
  933.         if( GetLine( str2, &strings, end )) {
  934.             struct LocaleStr   *s;
  935.  
  936.             if( s = AllocObject( IE_LOCALE_STRING )) {
  937.  
  938.             Insert(( struct List * )&IE.Locale->ExtraStrings, ( struct Node * )s, ( struct Node * )StrInsert );
  939.  
  940.             StrInsert = s;
  941.  
  942.             strcpy( s->ID,     str  );
  943.             strcpy( s->String, str2 );
  944.  
  945.             if( Free )
  946.                 s->Node.ln_Pri |= LOC_FREE;
  947.  
  948.             } else {
  949.             Stat( CatCompArray[ ERR_NOMEMORY ].cca_Str, TRUE, 0 );
  950.             break;
  951.             }
  952.  
  953.         } else
  954.             break;
  955.         }
  956.  
  957.         FreeMem( buffer, size );
  958.  
  959.     } else
  960.         Stat( CatCompArray[ ERR_NOMEMORY ].cca_Str, TRUE, 0 );
  961.  
  962.     Close( file );
  963.  
  964.     } else
  965.     Stat( CatCompArray[ ERR_IOERR ].cca_Str, TRUE, 0 );
  966. }
  967. ///
  968. /// GetLine
  969. BOOL GetLine( STRPTR string, UBYTE **buffer, UBYTE *end )
  970. {
  971.     BOOL    ret = FALSE, first = TRUE, ok = TRUE;
  972.     UBYTE  *ptr;
  973.  
  974.     ptr = *buffer;
  975.  
  976.     while(( ptr < end ) && ( ok )) {
  977.     UBYTE   c;
  978.  
  979.     switch( c = *ptr++ ) {
  980.  
  981.         case ';':
  982.         if( first ) {
  983.             /*  skip to EOL */
  984.             while( ptr < end ) {
  985.             if( *ptr++ == '\n' )
  986.                 break;
  987.             }
  988.         } else {
  989.             *string++ = ';';
  990.         }
  991.         break;
  992.  
  993.         case '\\':
  994.         if( ptr < end ) {
  995.             UBYTE   b;
  996.  
  997.             b = *ptr++;
  998.  
  999.             if( b != '\n' ) {
  1000.             *string++ = '\\';
  1001.             *string++ = b;
  1002.             }
  1003.         }
  1004.         break;
  1005.  
  1006.         case '\n':
  1007.         if(!( first ))
  1008.             ok = FALSE;
  1009.         break;
  1010.  
  1011.         default:
  1012.         *string++ = c;
  1013.         ret       = TRUE;
  1014.         first     = FALSE;
  1015.         break;
  1016.     }
  1017.     }
  1018.  
  1019.     *string = '\0';
  1020.     *buffer = ptr;
  1021.  
  1022.     return( ret );
  1023. }
  1024. ///
  1025.  
  1026. /// Import from Catalog
  1027. BOOL LOC_CatMenued( void )
  1028. {
  1029.     APTR    lock;
  1030.  
  1031.     LockAllWindows();
  1032.     lock = rtLockWindow( LocaleWnd );
  1033.  
  1034.     DetacheStrList();
  1035.  
  1036.     if( GetFile2( FALSE, CatCompArray[ ASL_IMPORT_STRINGS ].cca_Str, "#?.catalog",
  1037.           ASL_IMPORT_STRINGS, "catalog" )) {
  1038.     struct IFFHandle   *iff;
  1039.  
  1040.     if( iff = AllocIFF() ) {
  1041.  
  1042.         if( iff->iff_Stream = Open( allpath2, MODE_OLDFILE )) {
  1043.  
  1044.         InitIFFasDOS( iff );
  1045.  
  1046.         if(!( OpenIFF( iff, IFFF_READ ))) {
  1047.             ULONG   ret;
  1048.  
  1049.             PropChunk( iff, MAKE_ID( 'C', 'T', 'L', 'G' ), MAKE_ID( 'L', 'A', 'N', 'G' ));
  1050.             StopChunk( iff, MAKE_ID( 'C', 'T', 'L', 'G' ), MAKE_ID( 'S', 'T', 'R', 'S' ));
  1051.  
  1052.             ret = ParseIFF( iff, IFFPARSE_SCAN );
  1053.  
  1054.             if(( ret == 0 ) || ( ret == IFFERR_EOF )) {
  1055.             struct StoredProperty  *lang;
  1056.  
  1057.             if( lang = FindProp( iff, MAKE_ID( 'C', 'T', 'L', 'G' ), MAKE_ID( 'L', 'A', 'N', 'G' ))) {
  1058.                 struct ContextNode *strs;
  1059.  
  1060.                 strs = CurrentChunk( iff );
  1061.  
  1062.                 if( strs->cn_ID == MAKE_ID( 'S', 'T', 'R', 'S' )) {
  1063.                 LONG            size;
  1064.                 UBYTE          *ptr, *ptr2;
  1065.                 struct MinList  list;
  1066.                 TEXT            language[ 80 ];
  1067.  
  1068.                 strncpy( language, lang->sp_Data, lang->sp_Size );
  1069.  
  1070.                 NewList( &list );
  1071.  
  1072.                 size = strs->cn_Size;
  1073.  
  1074.                 if( ptr = ptr2 = AllocVec( size, MEMF_ANY )) {
  1075.  
  1076.                     ReadChunkBytes( iff, ptr, size );
  1077.  
  1078.                     do {
  1079.                     ULONG                       len = 0;
  1080.                     TEXT                        buffer[1024];
  1081.                     UBYTE                      *dest;
  1082.                     struct LocaleTranslation   *tran;
  1083.  
  1084.                     ptr  += 8;   // skip ID + len
  1085.                     size -= 8;
  1086.  
  1087.                     dest = buffer;
  1088.  
  1089.                     while( *ptr && ( size > 0 )) {
  1090.  
  1091.                         *dest = *ptr++;
  1092.  
  1093.                         if( *dest == '\n' ) {
  1094.                         *dest++ = '\\';
  1095.                         *dest   = 'n';
  1096.                         }
  1097.  
  1098.                         ++dest;
  1099.                         --size;
  1100.                     }
  1101.  
  1102.                     *dest = '\0';
  1103.  
  1104.                     ++ptr;
  1105.                     --size;
  1106.  
  1107.                     if( tran = AllocObject( IE_LOCALE_TRANSLATION )) {
  1108.  
  1109.                         AddTail(( struct List * )&list, ( struct Node * )tran );
  1110.  
  1111.                         if( tran->String = AllocVec( strlen( buffer ) + 1, MEMF_ANY ))
  1112.                         strcpy( tran->String, buffer );
  1113.                         else
  1114.                         DisplayBeep( Scr );
  1115.  
  1116.                         tran->Node.ln_Name = tran->String;
  1117.  
  1118.                     } else
  1119.                         DisplayBeep( Scr );
  1120.  
  1121.                     (ULONG)dest  = ((ULONG)ptr + 3 ) & ~3;
  1122.                     size -= dest - ptr;
  1123.                     ptr   = dest;
  1124.  
  1125.                     } while( size > 0 );
  1126.  
  1127.                     Import( language, &list );
  1128.  
  1129.                     FreeVec( ptr2 );
  1130.  
  1131.                 } else
  1132.                     DisplayBeep( Scr );
  1133.                 }
  1134.  
  1135.             } else
  1136.                 DisplayBeep( Scr );
  1137.  
  1138.             } else
  1139.             DisplayBeep( Scr );
  1140.  
  1141.             CloseIFF( iff );
  1142.  
  1143.         } else
  1144.             DisplayBeep( Scr );
  1145.  
  1146.         Close( iff->iff_Stream );
  1147.  
  1148.         } else
  1149.         DisplayBeep( Scr );
  1150.  
  1151.         FreeIFF( iff );
  1152.  
  1153.     } else
  1154.         DisplayBeep( Scr );
  1155.     }
  1156.  
  1157.     AttachStrList();
  1158.  
  1159.     rtUnlockWindow( LocaleWnd, lock );
  1160.     UnlockAllWindows();
  1161.  
  1162.     return( TRUE );
  1163. }
  1164. ///
  1165. /// Import from .ct         N/A
  1166. BOOL LOC_CtMenued( void )
  1167. {
  1168.     return( TRUE );
  1169. }
  1170. ///
  1171. /// Import
  1172. void Import( STRPTR Language, struct MinList *From )
  1173. {
  1174.     struct LocaleTranslation   *tran;
  1175.     struct LocaleLanguage      *lang;
  1176.     BOOL                        w;
  1177.     ULONG                       n;
  1178.  
  1179.     w = FALSE;
  1180.  
  1181.     for( n = 0, lang = (struct LocaleLanguage *)IE.Locale->Languages.mlh_Head; lang->Node.ln_Succ; lang = (struct LocaleLanguage *)lang->Node.ln_Succ, n++ ) {
  1182.     if( strcmp( Language, lang->Language ) == 0 ) {
  1183.         w = TRUE;
  1184.         break;
  1185.     }
  1186.     }
  1187.  
  1188.     if(!( w )) {
  1189.  
  1190.     lang = AllocObject( IE_LOCALE_LANGUAGE );
  1191.  
  1192.     strcpy( lang->Language, Language );
  1193.  
  1194.     AddTail(( struct List * )&IE.Locale->Languages, ( struct Node * )lang );
  1195.  
  1196.     n++;
  1197.     }
  1198.  
  1199.     for( tran = (struct LocaleTranslation *)From->mlh_Head; tran->Node.ln_Succ; tran = (struct LocaleTranslation *)tran->Node.ln_Succ )
  1200.     tran->Node.ln_Type = n;
  1201.  
  1202.     LayoutWindow( ImportWTags );
  1203.     w = OpenImportWindow();
  1204.     PostOpenWindow( ImportWTags );
  1205.  
  1206.     if( w )
  1207.     DisplayBeep( Scr );
  1208.     else {
  1209.  
  1210.     ImportList   = From;
  1211.     SelectedTran = NULL;
  1212.     EditingStr   = NULL;
  1213.  
  1214.     AttachImpLists();
  1215.  
  1216.     do {
  1217.         WaitPort( ImportWnd->UserPort );
  1218.     } while( HandleImportIDCMP() );
  1219.     }
  1220.  
  1221.     CloseImportWindow();
  1222.  
  1223.     while( tran = RemTail(( struct List * )From ))
  1224.     FreeObject( tran, IE_LOCALE_TRANSLATION );
  1225. }
  1226.  
  1227. void DetacheImpLists( void )
  1228. {
  1229.     ListTag[1] = (ULONG)~0;
  1230.  
  1231.     GT_SetGadgetAttrsA( ImportGadgets[ GD_IMP_From ], ImportWnd,
  1232.             NULL, (struct TagItem *)ListTag );
  1233.  
  1234.     GT_SetGadgetAttrsA( ImportGadgets[ GD_IMP_To ], ImportWnd,
  1235.             NULL, (struct TagItem *)ListTag );
  1236. }
  1237.  
  1238. void AttachImpLists( void )
  1239. {
  1240.     ListTag[1] = (ULONG)&IE.Locale->ExtraStrings;
  1241.     GT_SetGadgetAttrsA( ImportGadgets[ GD_IMP_To ], ImportWnd,
  1242.             NULL, (struct TagItem *)ListTag );
  1243.  
  1244.     List2Tag[3] = (ULONG)~0;
  1245.     GT_SetGadgetAttrsA( ImportGadgets[ GD_IMP_To ], ImportWnd,
  1246.             NULL, (struct TagItem *)&List2Tag[2] );
  1247.  
  1248.     ListTag[1] = (ULONG)ImportList;
  1249.     GT_SetGadgetAttrsA( ImportGadgets[ GD_IMP_From ], ImportWnd,
  1250.             NULL, (struct TagItem *)ListTag );
  1251.  
  1252.     List2Tag[3] = (ULONG)~0;
  1253.     GT_SetGadgetAttrsA( ImportGadgets[ GD_IMP_From ], ImportWnd,
  1254.             NULL, (struct TagItem *)&List2Tag[2] );
  1255.  
  1256.     EditingStr   = NULL;
  1257.     SelectedTran = NULL;
  1258. }
  1259.  
  1260. BOOL ImportCloseWindow( void )
  1261. {
  1262.     return( FALSE );
  1263. }
  1264.  
  1265. BOOL ImportVanillaKey( void )
  1266. {
  1267.     if( ImportMsg.Code == 27 )
  1268.     return( FALSE );
  1269.     else
  1270.     return( TRUE );
  1271. }
  1272.  
  1273. BOOL IMP_FromClicked( void )
  1274. {
  1275.     struct LocaleTranslation   *tran;
  1276.     ULONG                       i;
  1277.  
  1278.     tran = (struct LocaleTranslation *)ImportList->mlh_Head;
  1279.  
  1280.     for( i = 0; i < ImportMsg.Code; i++ )
  1281.     tran = (struct LocaleTranslation *)tran->Node.ln_Succ;
  1282.  
  1283.     SelectedTran = tran;
  1284.  
  1285.     return( TRUE );
  1286. }
  1287.  
  1288. BOOL IMP_ToClicked( void )
  1289. {
  1290.     struct LocaleStr   *str;
  1291.     ULONG               i;
  1292.  
  1293.     str = (struct LocaleTranslation *)IE.Locale->ExtraStrings.mlh_Head;
  1294.  
  1295.     for( i = 0; i < ImportMsg.Code; i++ )
  1296.     str = (struct LocaleStr *)str->Node.ln_Succ;
  1297.  
  1298.     EditingStr = str;
  1299.  
  1300.     return( TRUE );
  1301. }
  1302.  
  1303. BOOL IMP_LinkClicked( void )
  1304. {
  1305.     if( SelectedTran && EditingStr ) {
  1306.  
  1307.     DetacheImpLists();
  1308.  
  1309.     Remove(( struct Node * )SelectedTran );
  1310.  
  1311.     SelectedTran->Original = EditingStr->String;
  1312.  
  1313.     AddTail(( struct List * )&EditingStr->Translations, ( struct Node * )SelectedTran );
  1314.  
  1315.     AttachImpLists();
  1316.     }
  1317.  
  1318.     return( TRUE );
  1319. }
  1320. ///
  1321.  
  1322. /// GetStrings
  1323. BOOL GetStrings( void )
  1324. {
  1325.     struct WindowInfo  *wnd;
  1326.     BOOL                loc;
  1327.  
  1328.     if( StrList )
  1329.     return( TRUE );
  1330.  
  1331.     StrList = TRUE;
  1332.  
  1333.     if(( IE.ScreenData->Title[0] ) && ( IE.flags_2 & GENERASCR ))
  1334.     if(!( AddString( IE.ScreenData->Title )))
  1335.         return( FALSE );
  1336.  
  1337.     loc = ( IE.SrcFlags & LOCALIZE ) ? TRUE : FALSE;
  1338.  
  1339.     for( wnd = IE.win_list.mlh_Head; wnd->wi_succ; wnd = wnd->wi_succ ) {
  1340.     LONG                add;
  1341.     struct ITextNode   *txt;
  1342.  
  1343.     add = loc ? ( wnd->wi_Tags & W_LOC_TITLE ) : TRUE;
  1344.  
  1345.     if(( wnd->wi_Titolo[0] ) && ( add ))
  1346.         if(!( AddString( wnd->wi_Titolo )))
  1347.         return( FALSE );
  1348.  
  1349.     if( loc )
  1350.         add = wnd->wi_Tags & W_LOC_SCRTITLE;
  1351.     else
  1352.         add = TRUE;
  1353.  
  1354.     if(( wnd->wi_TitoloSchermo[0] ) && ( add ))
  1355.         if(!( AddString( wnd->wi_TitoloSchermo )))
  1356.         return( FALSE );
  1357.  
  1358.  
  1359.  
  1360.     if( loc )
  1361.         add = wnd->wi_Tags & W_LOC_GADGETS;
  1362.     else
  1363.         add = TRUE;
  1364.  
  1365.     if( add ) {
  1366.         struct GadgetBank  *bank;
  1367.  
  1368.         ProcessGadgets( &wnd->wi_Gadgets );
  1369.  
  1370.         for( bank = wnd->wi_GBanks.mlh_Head; bank->Node.ln_Succ; bank = bank->Node.ln_Succ )
  1371.         ProcessGadgets( &bank->Storage );
  1372.     }
  1373.  
  1374.  
  1375.     if( loc )
  1376.         add = wnd->wi_Tags & W_LOC_TEXTS;
  1377.     else
  1378.         add = TRUE;
  1379.  
  1380.     if( add )
  1381.         for( txt = wnd->wi_ITexts.mlh_Head; txt->itn_Node.ln_Succ; txt = txt->itn_Node.ln_Succ )
  1382.         if( txt->itn_Text[0] )
  1383.             if(!( AddString( txt->itn_Text )))
  1384.             return( FALSE );
  1385.  
  1386.     if( loc )
  1387.         add = wnd->wi_Tags & W_LOC_MENUS;
  1388.     else
  1389.         add = TRUE;
  1390.  
  1391.     if( add ) {
  1392.         struct MenuTitle   *menu;
  1393.         for( menu = wnd->wi_Menus.mlh_Head; menu->mt_Node.ln_Succ; menu = menu->mt_Node.ln_Succ ) {
  1394.         struct _MenuItem *item;
  1395.  
  1396.         if( menu->mt_Text[0] )
  1397.             if(!( AddString( menu->mt_Text )))
  1398.             return( FALSE );
  1399.  
  1400.         for( item = menu->mt_Items.mlh_Head; item->min_Node.ln_Succ; item = item->min_Node.ln_Succ ) {
  1401.             struct MenuSub *sub;
  1402.  
  1403.             if(( item->min_Text[0] ) && (!( item->min_Flags & M_BARLABEL )))
  1404.             if(!( AddString( item->min_Text )))
  1405.                 return( FALSE );
  1406.  
  1407.             if( item->min_CommKey[0] )
  1408.             if(!( AddString( item->min_CommKey )))
  1409.                 return( FALSE );
  1410.  
  1411.             for( sub = item->min_Subs.mlh_Head; sub->msn_Node.ln_Succ; sub = sub->msn_Node.ln_Succ ) {
  1412.  
  1413.             if(( sub->msn_Text[0] ) && (!( sub->msn_Flags & M_BARLABEL )))
  1414.                 if(!( AddString( sub->msn_Text )))
  1415.                 return( FALSE );
  1416.  
  1417.             if( sub->msn_CommKey[0] )
  1418.                 if(!( AddString( sub->msn_CommKey )))
  1419.                 return( FALSE );
  1420.             }
  1421.         }
  1422.         }
  1423.     }
  1424.  
  1425.     }
  1426.  
  1427.     FreeUnusedTranslations();
  1428.  
  1429.     return( TRUE );
  1430. }
  1431. ///
  1432. /// FreeUnusedTranslations
  1433. void FreeUnusedTranslations( void )
  1434. {
  1435.     struct LocaleTranslation   *tran;
  1436.  
  1437.     while( tran = (struct LocaleTranslation * ) RemTail(( struct List * )&IE.Locale->Translations ))
  1438.     FreeObject( tran, IE_LOCALE_TRANSLATION );
  1439. }
  1440. ///
  1441. /// PutStrings
  1442. void PutStrings( void )
  1443. {
  1444.     struct LocaleStr   *str;
  1445.     struct ArrayNode   *array;
  1446.  
  1447.     StrList = FALSE;
  1448.  
  1449.     for( str = IE.Locale->ExtraStrings.mlh_Head; str->Node.ln_Succ; str = str->Node.ln_Succ ) {
  1450.  
  1451.     if( str->Node.ln_Pri & LOC_GUI ) {
  1452.         struct LocaleStr           *pred;
  1453.         struct LocaleTranslation   *tran;
  1454.  
  1455.         pred = str->Node.ln_Pred;
  1456.  
  1457.         Remove(( struct Node * )str );
  1458.  
  1459.         while( tran = (struct LocaleTranslation *) RemHead(( struct List * )&str->Translations )) {
  1460.  
  1461.         tran->Original = str->Node.ln_Name;
  1462.  
  1463.         AddTail(( struct List * )&IE.Locale->Translations, ( struct Node * )tran );
  1464.         }
  1465.  
  1466.         FreeObject( str, IE_LOCALE_STRING );
  1467.  
  1468.         str = pred;
  1469.     }
  1470.     }
  1471.  
  1472.     while( array = (struct ArrayNode *) RemTail(( struct List * )&IE.Locale->Arrays ))
  1473.     FreeObject( array, IE_ARRAY_NODE );
  1474. }
  1475. ///
  1476.  
  1477. /// FreeLangStr
  1478. void FreeLangStr( UBYTE Lang )
  1479. {
  1480.     struct LocaleStr   *str;
  1481.  
  1482.     for( str = IE.Locale->ExtraStrings.mlh_Head; str->Node.ln_Succ; str = str->Node.ln_Succ ) {
  1483.  
  1484.     if( str->Node.ln_Type == Lang ) {
  1485.         struct LocaleStr   *pred;
  1486.  
  1487.         pred = str->Node.ln_Pred;
  1488.  
  1489.         Remove(( struct Node * )str );
  1490.         FreeObject( str, IE_LOCALE_STRING );
  1491.  
  1492.         str = pred;
  1493.  
  1494.     } else if( str->Node.ln_Type > Lang )
  1495.         str->Node.ln_Type -= 1;
  1496.     }
  1497. }
  1498. ///
  1499. /// FreeLocaleData
  1500. void FreeLocaleData( void )
  1501. {
  1502.     struct LocaleStr           *str;
  1503.     struct LocaleLanguage      *lang;
  1504.     struct LocaleTranslation   *tran;
  1505.     struct ArrayNode           *array;
  1506.  
  1507.     while( str = (struct LocaleStr *) RemTail(( struct List * )&IE.Locale->ExtraStrings ))
  1508.     FreeObject( str, IE_LOCALE_STRING );
  1509.  
  1510.     while( lang = (struct LocaleLanguage *) RemTail(( struct List * )&IE.Locale->Languages ))
  1511.     FreeObject( lang, IE_LOCALE_LANGUAGE );
  1512.  
  1513.     while( tran = (struct LocaleTranslation *) RemTail(( struct List * )&IE.Locale->Translations ))
  1514.     FreeObject( tran, IE_LOCALE_TRANSLATION );
  1515.  
  1516.     while( array = (struct ArrayNode *) RemTail(( struct List * )&IE.Locale->Arrays ))
  1517.     FreeObject( array, IE_ARRAY_NODE );
  1518. }
  1519. ///
  1520.  
  1521. /// CountArray
  1522. UWORD CountArray( UBYTE **Array )
  1523. {
  1524.     UWORD   cnt = 0;
  1525.  
  1526.     while( *Array++ )
  1527.     cnt += 1;
  1528.  
  1529.     return( cnt );
  1530. }
  1531. ///
  1532. /// CmpArrays
  1533. BOOL CmpArrays( UBYTE **First, struct MinList *Second )
  1534. {
  1535.     UWORD                   num, cnt;
  1536.     struct GadgetScelta    *gs;
  1537.  
  1538.     num = CountArray( First );
  1539.  
  1540.     gs = Second->mlh_Head;
  1541.     cnt = 0;
  1542.     while( gs->gs_Node.ln_Succ ) {
  1543.     cnt += 1;
  1544.     gs = gs->gs_Node.ln_Succ;
  1545.     }
  1546.  
  1547.     if( num != cnt )
  1548.     return( FALSE );
  1549.  
  1550.     gs = Second->mlh_Head;
  1551.  
  1552.     for( cnt = 0; cnt < num; cnt++ ) {
  1553.     if( strcmp( *First++, gs->gs_Testo ))
  1554.         return( FALSE );
  1555.     gs = gs->gs_Node.ln_Succ;
  1556.     }
  1557.  
  1558.     return( TRUE );
  1559. }
  1560. ///
  1561. /// FindString
  1562. struct LocaleStr *FindString( __A0 struct MinList *List, __A1 STRPTR String )
  1563. {
  1564.     struct LocaleStr   *str;
  1565.  
  1566.     for( str = List->mlh_Head; str->Node.ln_Succ; str = str->Node.ln_Succ )
  1567.     if( strcmp( str->Node.ln_Name, String ) == 0 )
  1568.         return( str );
  1569.  
  1570.     return( NULL );
  1571. }
  1572. ///
  1573. /// FindArray
  1574. struct ArrayNode *FindArray( __A0 struct MinList *List, __A1 struct MinList *Array )
  1575. {
  1576.     struct ArrayNode   *ar;
  1577.  
  1578.     for( ar = List->mlh_Head; ar->Next; ar = ar->Next )
  1579.     if( CmpArrays( ar->Array, Array ))
  1580.         return( ar );
  1581.  
  1582.     return( NULL );
  1583. }
  1584. ///
  1585. /// AddString
  1586. BOOL AddString( UBYTE *String )
  1587. {
  1588.     struct LocaleStr   *str;
  1589.  
  1590.     if(!( FindString( &IE.Locale->ExtraStrings, String ))) {
  1591.     struct LocaleTranslation   *tran;
  1592.  
  1593.     if(!( str = AllocObject( IE_LOCALE_STRING )))
  1594.         return( FALSE );
  1595.  
  1596.     AddTail(( struct List * )&IE.Locale->ExtraStrings, ( struct Node * )str );
  1597.  
  1598.     str->Node.ln_Pri  = LOC_GUI;
  1599.     str->Node.ln_Name = String;
  1600.  
  1601.     while( tran = GetTranslation( String ))
  1602.         AddTail(( struct List * )&str->Translations, ( struct Node * )tran );
  1603.     }
  1604.  
  1605.     return( TRUE );
  1606. }
  1607. ///
  1608. /// AddArray
  1609. BOOL AddArray( struct MinList *Items )
  1610. {
  1611.     struct ArrayNode       *ar;
  1612.     struct GadgetScelta    *gs;
  1613.     UBYTE                 **Array;
  1614.     UBYTE                   size = 4;
  1615.  
  1616.     if(!( FindArray( &IE.Locale->Arrays, Items ))) {
  1617.     if(!( ar = AllocObject( IE_ARRAY_NODE )))
  1618.         return( FALSE );
  1619.  
  1620.     AddTail(( struct List * )&IE.Locale->Arrays, ( struct Node * )ar );
  1621.  
  1622.     gs = Items->mlh_Head;
  1623.     while( gs = gs->gs_Node.ln_Succ )
  1624.         size += 4;
  1625.  
  1626.     if(!( Array = AllocVec( size, 0L )))
  1627.         return( FALSE );
  1628.  
  1629.     ar->Array = Array;
  1630.  
  1631.     for( gs = Items->mlh_Head; gs->gs_Node.ln_Succ; gs = gs->gs_Node.ln_Succ ) {
  1632.  
  1633.         *Array++ = gs->gs_Testo;
  1634.  
  1635.         if(!( AddString( gs->gs_Testo ))) {
  1636.         FreeVec( ar->Array );
  1637.         ar->Array = NULL;
  1638.         return( FALSE );
  1639.         }
  1640.     }
  1641.  
  1642.     *Array = NULL;
  1643.     }
  1644.  
  1645.     return( TRUE );
  1646. }
  1647. ///
  1648. /// ProcessGadgets
  1649. BOOL ProcessGadgets( struct MinList *Gadgets )
  1650. {
  1651.     struct GadgetInfo  *gad;
  1652.  
  1653.     for( gad = Gadgets->mlh_Head; gad->g_Node.ln_Succ; gad = gad->g_Node.ln_Succ ) {
  1654.  
  1655.     if(( gad->g_Kind < MIN_IEX_ID ) && ( gad->g_Titolo[0] ))
  1656.         if(!( AddString( gad->g_Titolo )))
  1657.         return( FALSE );
  1658.  
  1659.     switch( gad->g_Kind ) {
  1660.  
  1661.         case MX_KIND:
  1662.         case CYCLE_KIND:
  1663.         if(!( AddArray( &gad->g_Scelte )))
  1664.             return( FALSE );
  1665.         break;
  1666.  
  1667.         case LISTVIEW_KIND:
  1668.         {
  1669.             struct GadgetScelta *gs;
  1670.             for( gs = gad->g_Scelte.mlh_Head; gs->gs_Node.ln_Succ; gs = gs->gs_Node.ln_Succ )
  1671.             if(!( AddString( gs->gs_Testo )))
  1672.                 return( FALSE );
  1673.         }
  1674.         break;
  1675.  
  1676.         case TEXT_KIND:
  1677.         case STRING_KIND:
  1678.         if( *((UBYTE *)(gad->g_ExtraMem)) )
  1679.             if(!( AddString( gad->g_ExtraMem )))
  1680.             return( FALSE );
  1681.         break;
  1682.  
  1683.         case NUMBER_KIND:
  1684.         if(( ((struct NK)(gad->g_Data)).Format[0] ) && ( strcmp( ((struct NK)(gad->g_Data)).Format, "%ld" )))
  1685.             if(!( AddString( ((struct NK)(gad->g_Data)).Format )))
  1686.             return( FALSE );
  1687.         break;
  1688.  
  1689.         case SLIDER_KIND:
  1690.         if( ((struct SlK)(gad->g_Data)).Format[0] )
  1691.             if(!( AddString( ((struct SlK)(gad->g_Data)).Format )))
  1692.             return( FALSE );
  1693.         break;
  1694.     }
  1695.     }
  1696. }
  1697. ///
  1698. /// GetTranslation
  1699. struct LocaleTranslation *GetTranslation( STRPTR String )
  1700. {
  1701.     struct LocaleTranslation   *tran;
  1702.  
  1703.     for( tran = IE.Locale->Translations.mlh_Head; tran->Node.ln_Succ; tran = tran->Node.ln_Succ )
  1704.     if( strcmp( String, tran->Original ) == 0 ) {
  1705.         Remove(( struct Node * )tran );
  1706.         return( tran );
  1707.     }
  1708.  
  1709.     return( NULL );
  1710. }
  1711. ///
  1712.  
  1713. /// WriteCatalogs
  1714. void WriteCatalogs( STRPTR BaseName )
  1715. {
  1716.     if( IE.SrcFlags & LOCALIZE ) {
  1717.     struct LocaleStr   *str;
  1718.     ULONG               cnt;
  1719.     TEXT                Directory[256];
  1720.  
  1721.     strcpy( Directory, BaseName );
  1722.  
  1723.     *( FilePart( Directory )) = '\0';
  1724.  
  1725.     for( cnt = 0, str = IE.Locale->ExtraStrings.mlh_Head; str->Node.ln_Succ; str = str->Node.ln_Succ )
  1726.         if( str->Node.ln_Pri & LOC_GUI ) {
  1727.         sprintf( str->ID, "MSG_STRING_%ld", cnt++ );
  1728.         }
  1729.  
  1730.     if( IE.Locale->JoinFile[0] ) {
  1731.         str = StrInsert;
  1732.         ImportStrings( IE.Locale->JoinFile, TRUE );
  1733.         StrInsert = str;
  1734.     }
  1735.  
  1736.  
  1737.     if( WriteCD( Directory )) {
  1738.         ULONG   num;
  1739.  
  1740.         WriteCT( Directory, (UBYTE)-1 );
  1741.  
  1742.         num = CountNodes( &IE.Locale->Languages );
  1743.  
  1744.         for( cnt = 0; cnt < num; cnt++ )
  1745.         WriteCT( Directory, cnt );
  1746.     }
  1747.  
  1748.  
  1749.     for( str = IE.Locale->ExtraStrings.mlh_Head; str->Node.ln_Succ; str = str->Node.ln_Succ )
  1750.         if( str->Node.ln_Pri & LOC_FREE ) {
  1751.         struct LocaleStr   *pred;
  1752.  
  1753.         pred = str->Node.ln_Pred;
  1754.  
  1755.         Remove(( struct Node * )str );
  1756.  
  1757.         FreeObject( str, IE_LOCALE_STRING );
  1758.  
  1759.         str = pred;
  1760.         }
  1761.     }
  1762. }
  1763. ///
  1764. /// WriteCD
  1765. BOOL WriteCD( STRPTR Directory )
  1766. {
  1767.     TEXT    name[256];
  1768.     BOOL    ret;
  1769.  
  1770.     strcpy( name, Directory );
  1771.     strcat( name, IE.Locale->Catalog );
  1772.     strcat( name, ".cd" );
  1773.  
  1774.     if( ret = AskFile( name )) {
  1775.     BPTR    file;
  1776.  
  1777.     if( file = Open( name, MODE_NEWFILE )) {
  1778.         struct LocaleStr   *str;
  1779.  
  1780.         FPuts( file, ";\n"
  1781.              ";  CD File created by InterfaceEditor ©1994-1996 Simone Tellini\n"
  1782.              ";\n" );
  1783.  
  1784.         for( str = IE.Locale->ExtraStrings.mlh_Head; str->Node.ln_Succ; str = str->Node.ln_Succ )
  1785.         FPrintf( file, "%s (//)\n%s\n;\n", str->ID, str->Node.ln_Name );
  1786.  
  1787.         Close( file );
  1788.  
  1789.     } else
  1790.         Stat( CatCompArray[ ERR_IOERR ].cca_Str, TRUE, 0 );
  1791.     }
  1792.  
  1793.     return( ret );
  1794. }
  1795. ///
  1796. /// WriteCT
  1797. void WriteCT( STRPTR Path, UBYTE LangIndex )
  1798. {
  1799.     BPTR                    file;
  1800.     TEXT                    name[256];
  1801.     struct LocaleLanguage  *Lang = NULL;
  1802.  
  1803.     if( LangIndex != (UBYTE)-1 ) {
  1804.     ULONG   cnt;
  1805.  
  1806.     Lang = IE.Locale->Languages.mlh_Head;
  1807.  
  1808.     for( cnt = 0; cnt < LangIndex; cnt++ )
  1809.         Lang = Lang->Node.ln_Succ;
  1810.     }
  1811.  
  1812.     strcpy( name, Path );
  1813.  
  1814.     if( Lang )
  1815.     AddPart( name, Lang->File, 256 );
  1816.     else
  1817.     AddPart( name, IE.Locale->Catalog, 256 );
  1818.  
  1819.     strcat( name, ".ct" );
  1820.  
  1821.     if( file = Open( name, MODE_NEWFILE )) {
  1822.     struct LocaleStr   *str;
  1823.     struct DateTime     dt;
  1824.     TEXT                date[ LEN_DATSTRING ];
  1825.     UWORD               day, month, year;
  1826.  
  1827.     DateStamp( &dt.dat_Stamp );
  1828.  
  1829.     dt.dat_Format  = FORMAT_CDN;
  1830.     dt.dat_Flags   = 0;
  1831.     dt.dat_StrDate = date;
  1832.     dt.dat_StrTime = NULL;
  1833.     dt.dat_StrDay  = NULL;
  1834.  
  1835.     DateToStr( &dt );
  1836.  
  1837.     sscanf( date, "%hd-%hd-%hd", &day, &month, &year );
  1838.  
  1839.     FPuts( file, "## version $" );
  1840.  
  1841.     /*  I had to split the line because otherwise the c:Version
  1842.         command would get confused and the Installer script didn't
  1843.         work correctly.
  1844.     */
  1845.  
  1846.     FPrintf( file, "VER: %s.catalog %ld.0 (%ld.%ld.%ld)\n"
  1847.                "## codeset 0\n"
  1848.                "## language %s\n"
  1849.                ";\n",
  1850.          IE.Locale->Catalog,
  1851.          IE.Locale->Version,
  1852.          day, month, year,
  1853.          Lang ? (APTR)Lang->Language : "X" );
  1854.  
  1855.     for( str = IE.Locale->ExtraStrings.mlh_Head; str->Node.ln_Succ; str = str->Node.ln_Succ ) {
  1856.         STRPTR  tran = "";
  1857.         ULONG   max;
  1858.  
  1859.         max = CountNodes( &IE.Locale->Languages ) - 1;
  1860.  
  1861.         if( LangIndex != (UBYTE)-1 ) {
  1862.         struct LocaleTranslation   *t;
  1863.  
  1864.         for( t = str->Translations.mlh_Head; t->Node.ln_Succ; t = t->Node.ln_Succ ) {
  1865.  
  1866.             if( t->Node.ln_Type > max )
  1867.             t->Node.ln_Type = max;
  1868.  
  1869.             if( t->Node.ln_Type == LangIndex ) {
  1870.             tran = t->String;
  1871.             break;
  1872.             }
  1873.         }
  1874.         }
  1875.  
  1876.         FPrintf( file, "%s\n%s\n; %s\n;\n", str->ID, tran, str->Node.ln_Name );
  1877.     }
  1878.  
  1879.     Close( file );
  1880.     }
  1881. }
  1882. ///
  1883.